package com.rfid.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import biz.util.*;

import com.rfid.project.model.*;
import com.rfid.project.dao.*;
import com.rfid.project.exception.CannotDelException;
import com.rfid.project.exception.CannotUpdateException;
import com.mysema.query.BooleanBuilder;

import java.util.List;

@Service
@Transactional
public class AuthorityService {

	@Autowired
	private AuthorityDao authorityDao;

	@Autowired
	private PositionAuthorityDao positionAuthorityDao;

	private QAuthority $ = QAuthority.authority;

	private QPositionAuthority $_ = QPositionAuthority.positionAuthority;

	@Autowired
	public void setAuthorityDao(AuthorityDao authorityDao) {
		this.authorityDao = authorityDao;
	}

	@Autowired
	public void setPositionAuthorityDao(
			PositionAuthorityDao positionAuthorityDao) {
		this.positionAuthorityDao = positionAuthorityDao;
	}

	public List<Authority> findAll() {
		return ListUtil.toList(authorityDao.findAll());
	}

	public List<Authority> findAll(String code, String name, String remark,
			String orderByAttribute) {
		BooleanBuilder condition = new BooleanBuilder();

		if (StringUtil.isNotEmpty(code)) {
			condition.and($.code.contains(code));
		}

		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}

		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}

		return ListUtil.toList(authorityDao.findAll(condition));
	}

	public Page<Authority> findAll(String code, String name, String remark,
			int pageNumber, int pageSize, String sortAttribute,
			String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();

		if (StringUtil.isNotEmpty(code)) {
			condition.and($.code.contains(code));
		}
		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}
		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}

		
		
		Sort sortObject_1 = new Sort(Direction.DESC, "orderNumber");

		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize,
				sortObject_1);
		return authorityDao.findAll(condition, pageRequest);

	}

	public Authority getAuthority(Long id) {
		return authorityDao.getOne(id);
	}

	public void deleteAuthority(Long id) throws CannotDelException {
		if (this.findPositionauthByAuth(id)) {
			throw new CannotDelException("权限已经被人员权限引用，请先删除人员权限或修改人员权限的引用！");
		} else {
			this.authorityDao.delete(id);
		}
	}

	private boolean findPositionauthByAuth(Long authorityId) {
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($_.authority.id.eq(authorityId));
		return this.positionAuthorityDao.count(condition) > 0;
	}

	public void saveAuthority(Authority authority) throws CannotUpdateException {
		if (null == authority.getOrderNumber()) {
			authority.setOrderNumber(this.getOrderNumber());
		}
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.name.eq(authority.getName()));
		Authority temp = this.authorityDao.findOne(condition);
		Long id = authority.getId();
		if (null == id) {
			if(null != temp){
				throw new CannotUpdateException("权限名称已存在，无法添加！");
			}
		} else {
			if (null!= temp && !id.equals(temp.getId())) {
				throw new CannotUpdateException("权限名称已存在，无法修改！");
			}
		}
		this.authorityDao.save(authority);
	}

	private int getOrderNumber() {
		BooleanBuilder condition = new BooleanBuilder();
		Sort sortObject = new Sort(Direction.DESC, "orderNumber");
		PageRequest pageRequest = new PageRequest(0, 1, sortObject);
		Page<Authority> items = this.authorityDao.findAll(condition,
				pageRequest);
		if (items.getTotalElements() > 0) {
			Authority item = items.getContent().get(0);
			return item.getOrderNumber() + 1;
		}
		return 1;
	}
	
	public boolean changeOrderNumber(Long id, Long targetId){
		Authority currentModule = this.authorityDao.findOne(id);
		Authority targetModule = this.authorityDao.findOne(targetId);
		int orderNumber = currentModule.getOrderNumber();
		currentModule.setOrderNumber(targetModule.getOrderNumber());
		targetModule.setOrderNumber(orderNumber);
		
		this.authorityDao.save(currentModule);
		this.authorityDao.save(targetModule);
		return true;
	}

	public Authority findOne(Long id) {
		return this.authorityDao.findOne(id);
	}

}
